import os
import sys
import time
import logging
import configparser
import subprocess
import importlib.util
import requests

# 保证可以import到项目根目录下的config.py
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from config import ENV, CONFIG_PATH, setup_logger

# 日志工具函数

def log_info(msg):
    logging.info(msg)

def log_error(msg):
    logging.error(msg)

# 导入企业微信推送功能
try:
    from api.wechat_push import send_wechat_notification
    WECHAT_PUSH_AVAILABLE = True
except ImportError:
    log_error("企业微信推送模块导入失败，将跳过推送功能")
    WECHAT_PUSH_AVAILABLE = False

def send_record_notification(script_name, output_path, result, error_msg=None):
    """
    发送录制脚本完成通知
    :param script_name: 脚本文件名
    :param output_path: 输出文件路径
    :param result: 执行结果 (成功/失败)
    :param error_msg: 错误信息（可选）
    """
    if not WECHAT_PUSH_AVAILABLE:
        log_info("企业微信推送功能不可用，跳过通知发送")
        return
    
    try:
        # 准备推送数据
        custom_data = {
            "script_name": script_name or "未知脚本",
            "file_path": output_path or "未知路径",
            "environment": ENV
        }
        
        # 如果有错误信息，添加到数据中
        if error_msg:
            custom_data["error_message"] = error_msg
            
        # 获取文件大小信息
        if output_path and os.path.exists(output_path):
            file_size = os.path.getsize(output_path)
            custom_data["file_size"] = f"{file_size} bytes"
            
            # 读取文件行数
            try:
                with open(output_path, 'r', encoding='utf-8') as f:
                    line_count = sum(1 for _ in f)
                custom_data["line_count"] = f"{line_count} 行"
            except:
                custom_data["line_count"] = "未知"
        
        # 发送通知
        log_info(f"准备发送录制脚本完成通知: {result}")
        success = send_wechat_notification(
            template_type="record",
            result=result,
            custom_data=custom_data
        )
        
        if success:
            log_info("✅ 录制完成通知发送成功")
        else:
            log_error("❌ 录制完成通知发送失败")
            
    except Exception as e:
        log_error(f"发送录制完成通知异常: {e}")

# 获取当前脚本所在的项目根目录
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
API_LOGIN_PATH = os.path.join(BASE_DIR, 'api', 'login.py')
PWL_DIR = os.path.join(BASE_DIR, 'pwl')

# 动态导入login.py中的getCurrentLoginInfo函数
def import_getCurrentLoginInfo():
    login_path = os.path.join(BASE_DIR, 'api', 'login.py')
    spec = importlib.util.spec_from_file_location("login", login_path)
    login = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(login)
    return login.getCurrentLoginInfo

def call_login():
    """
    调用登录接口，刷新 access_token 并写入 config.ini。
    """
    try:
        log_info("调用登录接口，获取 access_token ...")
        # 调用 login.py，刷新 token
        result = subprocess.run(
            [sys.executable, API_LOGIN_PATH, ENV],
            capture_output=True, text=True, encoding='utf-8'
        )
        if result.returncode == 0:
            log_info("登录接口调用成功")
            log_info(result.stdout)
        else:
            log_error(f"登录接口调用失败: {result.stderr}")
            raise Exception("登录失败")
    except Exception as e:
        log_error(f"调用登录接口异常: {e}")
        raise

def get_next_record_filename() -> str:
    """
    获取下一个录制脚本文件名，格式为test_record_001.py
    :return: 新的文件名
    """
    import glob
    
    # 查找现有的test_record_*.py文件
    pattern = os.path.join(PWL_DIR, "test_record_*.py")
    existing_files = glob.glob(pattern)
    
    if not existing_files:
        return "test_record_001.py"
    
    # 提取所有现有文件的序号
    numbers = []
    for file_path in existing_files:
        filename = os.path.basename(file_path)
        # 从test_record_001.py中提取001
        if filename.startswith("test_record_") and filename.endswith(".py"):
            try:
                number_str = filename[12:-3]  # 去掉"test_record_"和".py"
                numbers.append(int(number_str))
            except ValueError:
                continue
    
    # 找到下一个可用的序号
    if numbers:
        next_number = max(numbers) + 1
    else:
        next_number = 1
    
    return f"test_record_{next_number:03d}.py"

def run_codegen(token):
    """
    读取 config.ini 中的 url 模板和 token，生成 playwright 自动化脚本，文件名为test_record_001格式。
    """
    output_path = None
    script_name = None
    
    try:
        config = configparser.ConfigParser()
        config.read(CONFIG_PATH, encoding='utf-8')
        url_template = config.get('playwright', 'url')
        # 用 token 替换 url 模板中的占位符
        url = url_template.format(token=token)
        # 获取下一个录制脚本文件名
        script_name = get_next_record_filename()
        output_path = os.path.join(PWL_DIR, script_name)
        
        log_info(f"开始执行 playwright codegen，URL: {url}")
        codegen_cmd = f'playwright codegen "{url}" --output="{output_path}"'
        # 执行 playwright codegen 命令
        ret = os.system(codegen_cmd)
        
        if ret == 0:
            log_info(f"playwright codegen 执行成功，文件: {output_path}")
            
            # 检查文件是否真正生成且有内容
            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                log_info(f"录制脚本生成成功: {script_name}")
                
                # 发送企业微信录制成功通知
                send_record_notification(script_name, output_path, "成功")
                
                return output_path
            else:
                log_error(f"录制脚本文件生成失败或文件为空: {output_path}")
                send_record_notification(script_name, output_path, "失败", "文件生成失败或为空")
                raise Exception("录制脚本文件生成失败")
        else:
            log_error(f"playwright codegen 执行失败，返回码: {ret}")
            send_record_notification(script_name, output_path, "失败", f"playwright执行失败，返回码: {ret}")
            raise Exception(f"playwright codegen执行失败: {ret}")
            
    except Exception as e:
        log_error(f"playwright codegen 执行异常: {e}")
        send_record_notification(script_name, output_path, "失败", str(e))
        raise

def main():
    """
    主流程：先判断token有效性，有效则跳过登录，否则登录后再生成 playwright 脚本。
    """
    setup_logger()
    try:
        log_info(f"自动化流程开始 ... 当前环境: {ENV}")
        # 动态导入login.py的getCurrentLoginInfo
        getCurrentLoginInfo = import_getCurrentLoginInfo()
        token_valid = getCurrentLoginInfo()
        if token_valid:
            log_info("token有效，跳过登录。")
        else:
            log_info("token无效或不存在，调用登录接口...")
            call_login()
        # 登录后重新读取最新token
        config = configparser.ConfigParser()
        config.read(CONFIG_PATH, encoding='utf-8')
        token = config.get('token', 'access_token', fallback=None)
        if not token:
            log_error('登录后未获取到token，流程终止。')
            return
        log_info(f'当前使用的token: {token}')
        run_codegen(token)
        log_info("自动化流程结束。")
    except Exception as e:
        log_error(f"自动化流程异常终止: {e}")

if __name__ == "__main__":
    main()